/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package domain;

import java.util.ArrayList;
import java.lang.String;
import java.util.Queue;
import java.util.LinkedList;
/**
 *
 * @author andreu.marimon
 */
public class PruebaTrie {

    public static void insertWords (ArrayList<String> words) {
        words.add("casa");
        words.add ("casal");
        words.add ("cotxe");
        words.add ("vi");
        words.add ("guitarra");
        words.add ("piano");
        words.add ("estrella");
        words.add ("estela");
        words.add ("via");
        words.add ("colom");
        words.add ("colomar");
        words.add ("calamar");
        words.add ("guitarrista");
        words.add ("objecte");
        words.add ("objectiu");
        words.add ("carrer");
        words.add ("carrero");
        words.add ("carreta");
        words.add ("carro");
        words.add ("cerca");
        words.add ("aviat");
        words.add ("moneda");
        words.add ("jersei");
        words.add ("xiuxiuejar");
        words.add ("xiuxiueig");
        words.add ("darrera");
        words.add ("darrer");
        words.add ("sol");
        words.add ("remoli");
        words.add ("perill");
        words.add ("periclitar");
        words.add ("circumferencia");
        words.add ("riu");
        words.add ("bomba");
        words.add ("almogaver");
        words.add ("facultatiu");
        words.add ("sorra");
        words.add ("verd");
        words.add ("verdissa");
        words.add ("menjar");
        words.add ("llit");
        words.add ("filaberqui");
        words.add ("home");
        words.add ("iode");
        words.add ("tornavis");
        words.add ("tornar");
        words.add ("tanoca");
        words.add ("transformar");
        words.add ("tou");
        words.add ("tous");
        words.add ("tort");
        words.add ("torta");
        words.add ("tortell");
        words.add ("tractor");
        words.add ("similar");
        words.add ("sensacio");
        words.add ("avinguda");
        words.add ("avenir");
        words.add ("arbre");
        words.add ("zinc");
        words.add ("zebra");
        words.add ("humanitat");
        words.add ("volatil");
        words.add ("mandolina");
        words.add ("traduccio");
        words.add ("tradicio");
        words.add ("trompeta");
        words.add ("catalunya");
        words.add ("barret");
        words.add ("barretina");
        words.add ("cantina");
        words.add ("forat");
        words.add ("foradar");
        words.add ("forani");
        words.add ("foc");
        words.add ("fil");
        words.add ("corona");
        words.add ("coronar");
        words.add ("sesam");
        words.add ("silici");
        words.add ("silenci");
        words.add ("silencios");
        words.add ("camell");
        words.add ("corall");
        words.add ("drac");
        words.add ("dibuix");
        words.add ("divertit");
        words.add ("diversio");
        words.add ("esdruixola");
        words.add ("veterinari");
        words.add ("veterinaria");
        words.add ("veridic");
        words.add ("vergonya");
        words.add ("bigoti");
        words.add ("cigarreta");
        words.add ("programador");
        words.add ("programari");
        words.add ("pilota");
        words.add ("pinya");
        words.add ("pinyo");
        words.add ("heura");
        words.add ("heuristica");
        words.add ("hipotetic");
        words.add ("hipopotam");
        words.add ("hipocondriac");
        words.add ("hipocrita");
        words.add ("invent");
        words.add ("escriure");
        words.add ("netejar");
        words.add ("llegir");
        words.add ("lector");
        words.add ("lectura");
        words.add ("liberal");
        words.add ("social");
        words.add ("sincer");
        words.add ("mentider");
        words.add ("maranya");
    }

    //------------------------------------------------------------------------//
    //-------------------------randomString (int lenght)----------------------//
    //------------------------------------------------------------------------//
    // Retorna un String aleatori de mida lenght

    public static String randomString (int lenght) {
        char[] elements={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','ñ','o','p','q','r','s','t','u','v','w','x','y','z'};
        char[] set = new char[lenght];
        for(int i=0;i<lenght;i++){
            int el = (int)(Math.random()*27);
            set[i] = (char)elements[el];
        }
        return new String(set);
    }

    //------------------------------------------------------------------------//
    //-----insertOnTrie (Trie<String> testTrie, ArrayList<String> words)------//
    //------------------------------------------------------------------------//
    // Insereix a testTrie totes les paraules de words

    public static void insertOnTrie (Trie<String> testTrie, ArrayList<String> words) {
        for (String singleWord : words) {
            testTrie.put (singleWord, singleWord);
        }
    }

    //-------------------------------------------------------------------------//
    //testInsertTrie (Trie<String> testTrie, ArrayList<String> words, int show)//
    //-------------------------------------------------------------------------//
    // Retorna quantes de les paraules de words es troben a testTrie i afegeix
    // a missingWords aquelles que no ha trobat

    public static boolean testInsertTrie (Trie<String> testTrie, ArrayList<String> words, int show) {
        int count = 0;
        ArrayList<String> missingWords = new ArrayList<String>();
        for (String singleWord : words) {
            if (testTrie.exists(singleWord)) ++ count;
            else missingWords.add(singleWord);
        }
        if (show != 0) {
            System.out.println("El trie detecta l'existencia de "+count+
                " paraules de les "+words.size()+" inserides");
            if (count < words.size()) {
                System.out.println("Les paraules no trobades son"+missingWords.toString());
            }
        }
        return count == words.size();
    }

    //------------------------------------------------------------------------//
    //-testFinals (Trie<String> testTrie, ArrayList <String> words), int show-//
    //------------------------------------------------------------------------//
    // Comprova quantes paraules (nodes finals) te el trie

    public static boolean testFinals (Trie<String> testTrie, ArrayList <String> words, int show) {
        Queue <Trie<String>> allNodesInTrieQueue = new LinkedList <Trie<String>>();
        ArrayList <Trie<String>> allNodesInTrie = new ArrayList <Trie<String>>();
        allNodesInTrieQueue.addAll(testTrie.getChildTries());
        int count = 0;
        while (!allNodesInTrieQueue.isEmpty()) {
            allNodesInTrie.add (allNodesInTrieQueue.peek());
            allNodesInTrieQueue.addAll(allNodesInTrieQueue.poll().getChildTries());
        }
        for (Trie<String> singleWord: allNodesInTrie) {
            if (singleWord.isFinal()) ++count;
        }

        if (show != 0) System.out.println("El trie detecta l'existencia de "+count+
                " paraules havent-ne inserit "+words.size());
        return count == words.size();
    }

    //------------------------------------------------------------------------//
    //----testT (Trie<String> testTrie, ArrayList <String> words, int show)---//
    //------------------------------------------------------------------------//
    // Comprova que totes les estructures siguin correctes. Mostrar = 0 no escriu
    // per pantalla. Altrament escriu totes les equivalencies

    public static boolean testT (Trie<String> testTrie, ArrayList <String> words, int show) {
        int count = 0;
        for (String singleWord : words) {
            if (testTrie.get(singleWord).equals(singleWord)) ++count;
            if (show != 0) System.out.println(singleWord +" = "+testTrie.get(singleWord));
        }
        return count == words.size();
    }

    //------------------------------------------------------------------------//
    // testTNumber (Trie<String> testTrie, ArrayList <String> words, int show)//
    //------------------------------------------------------------------------//
    // Comprova que totes les estructures siguin correctes. Mostrar = 0 no escriu
    // per pantalla. Altrament escriu totes les equivalencies

    public static boolean testTNumber (Trie<String> testTrie, ArrayList <String> words, int show) {
       if (show != 0) System.out.println("El trie detecta l'existencia de "+testTrie.getAll().size()+
                " estructures de dades associades als nodes finals de les "+words.size()+" paraules"
                + " inserides");
       return testTrie.getAll().size() == words.size();
    }

    //------------------------------------------------------------------------//
    //-testAssign (Trie<String> testTrie, ArrayList <String> words, int show)-//
    //------------------------------------------------------------------------//
    // Comprova que s'assignen correctament noves estructures als ndoes. Mostrar = 0 no escriu
    // per pantalla. Altrament escriu totes les equivalencies

    public static boolean testAssign (Trie<String> testTrie, ArrayList <String> words, int show) {
        boolean result = false;
        testTNumber (testTrie, words, show);
        if (show != 0) {
           System.out.println("Assignem una nova estructura de dades");
        }
       testTrie.assign(words.get(0).substring(0,1), "NewT");
       testTNumber (testTrie, words, show);
       result = testTrie.getAll().size() == words.size()+1;
       if (show !=0) System.out.println("Comprovem que no canvia la quantitat de nodes finals:");
       return testFinals (testTrie,words,show) && result;
    }

    //------------------------------------------------------------------------//
    //- testLabel (Trie<String> testTrie, ArrayList <String> words, int show)-//
    //------------------------------------------------------------------------//
    // Comprova que totes les etiquetes siguin correctes. Mostrar = 0 no escriu
    // per pantalla. Altrament escriu totes les equivalencies

    public static boolean testSingleLabel (Trie<String> testTrie, String singleWord, int show) {
        boolean result = true;
        int wordSize = singleWord.length();
        if (show != 0) System.out.println("Analitzem la paraula: "+singleWord);
        for (int i = 1; i <= wordSize; i++) {
            if (show != 0 )System.out.println("Etiqueta de l'ultim node de "+ singleWord.substring(0, i)
                    +" es: "+ testTrie.getTrie(singleWord.substring(0, i)).getLabel());
            if (!singleWord.substring(i-1, i).equals(testTrie.getTrie(singleWord.substring(0, i)).getLabel()) ) result = false;
        }
        return result;
    }

    //------------------------------------------------------------------------//
    //- testLabel (Trie<String> testTrie, ArrayList <String> words, int show)-//
    //------------------------------------------------------------------------//
    // Comprova que totes les etiquetes siguin correctes. Mostrar = 0 no escriu
    // per pantalla. Altrament escriu totes les equivalencies

    public static boolean testLabels (Trie<String> testTrie, ArrayList <String> words, int show) {
        boolean result = true;
        for (String singleWord : words) {
            if (!testSingleLabel(testTrie,singleWord,show)) result = false;
        }
        return result;
    }

    //------------------------------------------------------------------------//
    //-testSearch (Trie<String> testTrie, ArrayList <String> words, int show)-//
    //------------------------------------------------------------------------//
    // Comprova que la cerca de paraules no inserides sigui nula. Mostrar = 0 no escriu
    // per pantalla. Altrament escriu totes les equivalencies

    public static boolean testSearch (Trie<String> testTrie, ArrayList <String> words, int show) {
        boolean result = true;
        if (show != 0) System.out.println("Comprovem que paraules aleatories de diferent mida i que no siguin cap de les"
                + " afegides no es trobin al trie: ");
        for (int i = 1; i <= 6; ++i) {
            String singleWord = randomString (i);
            while (words.contains(singleWord)) {
                singleWord = randomString (i);
            }
            result = result && !testTrie.exists(singleWord);
            if (show != 0 && result) System.out.println("La paraula "+singleWord+" no es al trie");
            else if (show !=0) System.out.println("La paraula "+singleWord+" es al trie");
        }
        if (show != 0) System.out.println("Comprovem que una paraula que no sigui cap de les afegides"
                + " al trie, pero comenci igual que una d'elles, no apareixi al trie");
        for (int j = 0; j <= 6; ++j) {
            int i = 0;
            String singleWord = words.get(j+i).substring(0, words.get(j+i).length()-1);
            while (words.contains(singleWord)) {
                singleWord = words.get(j+i).substring(0, words.get(j+i).length()-1);
                ++i;
            }
            result = result && !testTrie.exists(singleWord);
            if (show != 0 && result) System.out.println("La paraula "+singleWord+" no es al trie");
            else if (show !=0) System.out.println("La paraula "+singleWord+" es al trie");
        }
        return result;
    }

    //------------------------------------------------------------------------//
    //----------------------------main(String[] args)-------------------------//
    //------------------------------------------------------------------------//
    // Executa els jocs de proves

    public static void main(String[] args) {
        int show = 1;
        // Crea una llista de paraules per insertar al trie
        ArrayList <String> words = new ArrayList <String>();
        insertWords (words);
        System.out.println("Prova amb diccionari complet. Conté "+ words.size()+
                " paraules amb tot tipus de casos i relacions entre elles\n");

        // Inserta les paraules al trie
        System.out.println("Comprovem que el Trie admet la inserció de totes les paraules:");
        Trie <String> testTrie = new Trie<String>();
        insertOnTrie (testTrie, words);
        System.out.println("Ok\n");

        // Comprova que el trie contingui totes les paraules inserides
        System.out.println("Comprovem que el Trie contingui totes les paraules que hem inserit:");
        if (testInsertTrie(testTrie, words, show)) System.out.println("Ok\n");
        else System.out.println("Bad Test\n");

        //Comprova la quantitat de paraules que conté el trie
        System.out.println("Comprovem que el nombre de paraules que conté el trie (nodes finals)"
                + " sigui igual al nombre de paraules inserides:");
        if (testFinals(testTrie, words, show)) System.out.println("Ok\n");
        else System.out.println("Bad Test\n");

        //Comprova la quantitat d'estructures de dades no nules que conté el trie
        System.out.println("Comprovem quantes estructures de dades no nulles te el Trie:");
        if (testTNumber(testTrie, words, show)) System.out.println("Ok\n");
        else System.out.println("Bad Test\n");

        //Comprova que les estructures de dades associades siguin correctes
        System.out.println("Comprovem que les estructures de dades siguin correctes:");
        if (testT(testTrie, words, show)) System.out.println("Ok\n");
        else System.out.println("Bad Test\n");

        //Comprova que l'assignacio d'estructures de dades es realitza correctament
        System.out.println("Comprovem que l'assignacio d'estructures de dades es realitza correctament:");
        if (testAssign(testTrie, words, show)) System.out.println("Ok\n");
        else System.out.println("Bad Test\n");

        //Comprova que les etiquetes son correctes
        System.out.println("Comprovem que les etiquetes son correctes:");
        if (testLabels(testTrie, words, show)) System.out.println("Ok\n");
        else System.out.println("Bad Test\n");

        //Comprova que la cerca de paraules no inserides sigui nula
        System.out.println("Comprovem que la cerca de paraules no inserides sigui nula");
        if (testSearch(testTrie, words, show)) System.out.println("Ok\n");
        else System.out.println("Bad Test\n");
    }
}
